﻿using SqlSugar;
using System.Reflection;
using Zy.Shared.Repository.ClickHouse.DbContext;
using Zy.Shared.Repository.ClickHouse.Repositorys;
using Zy.Shared.Repository.ClickHouse;
using Microsoft.Extensions.Configuration;
using Zy.Shared.ServicesLocator;
using Microsoft.Extensions.Logging;

namespace Microsoft.Extensions.DependencyInjection;

public static class RegisterClickhouse
{
    public static IServiceCollection AddZySqlSugarCoreClickHouse<T>(this IServiceCollection services, IConfiguration config)
    {
        if(!typeof(T).Assembly.ExportedTypes.Any(type => type.IsAssignableTo(typeof(SqlSugarEntity)) && !type.IsAbstract && type.IsPublic)) 
            return services;
        var sqlSugar = ServiceLocator.Instance?.GetService<ISqlSugarClient>() ?? new SqlSugarScope(
                   new ConnectionConfig()
                   {
                       DbType = SqlSugar.DbType.ClickHouse,//数据库类型
                       ConnectionString = config.GetConnectionString("ClickHouseConnection") ?? "",//配置文件中的数据库链接key值
                       IsAutoCloseConnection = true,//是否自动关闭连接
                       InitKeyType = InitKeyType.Attribute
                   },
                   db =>
                   {

                       //单例参数配置，所有上下文生效
                       db.Aop.OnLogExecuting = (sql, pars) =>
                       {
                           var log = ServiceLocator.Instance?.GetService<ILogger>();
                           log?.LogDebug(sql, pars);
                       };
                       db.Aop.DataExecuting = (sql, pars) =>
                       {
                           var scope = services.BuildServiceProvider().CreateScope();
                           var appService = scope.ServiceProvider.GetRequiredService<SqlSugarDbContext>();
                           appService.SetAuditFields(sql, pars);
                       };
                   }
               );
        if (!services.Any(s => s.ServiceType == typeof(SqlSugarDbContext)))
        {
            services.AddScoped(typeof(SqlSugarDbContext));           
            services.AddSingleton<ISqlSugarClient>(sqlSugar);//这边是SqlSugarScope用AddSingleton     
            services.TryAddScoped(typeof(ISqlSugarRespository<>), typeof(SqlSugarRespository<>));
        }
        var list = typeof(T).Assembly.ExportedTypes.Where(type => type.IsAssignableTo(typeof(SqlSugarEntity)) && !type.IsAbstract && type.IsPublic) ?? throw new NullReferenceException("ISqlSugarEntityInfo");

        SqlSugarDbContext.InitTables(list.ToList(), sqlSugar);
        return services;
    }
}